package org.mech.sefer.entity.converter;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.mech.sefer.entity.dao.Dao;
import org.mech.sefer.entity.model.AbstractEntity;
import org.mech.sefer.model.AbstractTransferObject;

public abstract class AbstractEntityConverter<E extends AbstractEntity, TO extends AbstractTransferObject<?>>
		extends AbstractConverter<E, TO> implements BidiConverter<E, TO> {
	
	protected Dao<E> dao;

	protected abstract E createEntityInstance();

	protected abstract E doReverseConvert(TO transferObject, E entity);

	public E reverseConvert(TO transferObject, E entity) throws ConversionException {
		return doReverseConvert(transferObject, load(transferObject));
	};

	@Override
	public Collection<E> reverseConvertAll(Collection<TO> objects)
			throws ConversionException {
		List<E> list = new ArrayList<E>();

		for (TO transferObject : objects) {
			list.add(reverseConvert(transferObject, load(transferObject)));
		}

		return list;
	}

	private E load(TO transferObject) throws ConversionException {
		E fromObject;
		
		final Serializable id = transferObject.getId();

		if (id == null) {
			fromObject = createEntityInstance();
		} else {
			fromObject = getDao().findById(id);

			if (fromObject == null) {
				throw new ConversionException("Object with given id '" + id
						+ "' is not present in DB");
			}
		}
		return fromObject;
	}

	public Dao<E> getDao() {
		return dao;
	}

	public void setDao(Dao<E> dao) {
		this.dao = dao;
	}

}
